package com.inspection.service.impl;

import com.google.common.collect.Lists;
import com.inspection.constant.DepartmentTypeEnum;
import com.inspection.constant.YesNoEnum;
import com.inspection.dao.InspectionDepartmentDao;
import com.inspection.entity.InspectionBranchDO;
import com.inspection.entity.InspectionDepartmentDO;
import com.inspection.model.dto.InspectionDepartmentDTO;
import com.inspection.model.dto.InspectionDepartmentQueryDTO;
import com.inspection.service.InspectionDepartmentService;
import com.inspection.support.AssertUtils;
import com.inspection.support.model.BusinessBaseException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.Predicate;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author zhaoqi
 * @since 2020-11-10
 */
@Service
public class InspectionDepartmentServiceImpl implements InspectionDepartmentService {

    @Autowired
    private InspectionDepartmentDao inspectionDepartmentDao;

    @Override
    public List<InspectionDepartmentDO> queryDepartment(InspectionDepartmentQueryDTO query) {
        Sort sort = new Sort(Sort.Direction.DESC, "id");
        List<InspectionDepartmentDO> depts = inspectionDepartmentDao.findAll((Specification<InspectionDepartmentDO>) (root, criteriaQuery, criteriaBuilder) -> {

            List<Predicate> predicates = Lists.newArrayList();
            predicates.add(criteriaBuilder.equal(root.get("isDel"), 0));

            if (!StringUtils.isEmpty(query.getIsLeafNode())) {
                predicates.add(criteriaBuilder.equal(root.get("isLeafNode"), query.getIsLeafNode()));
            }
            if (!StringUtils.isEmpty(query.getDeptType())) {
                predicates.add(criteriaBuilder.equal(root.get("deptType"), query.getDeptType()));
            }
            if (!StringUtils.isEmpty(query.getDeptName())) {
                predicates.add(criteriaBuilder.like(root.get("deptName"), "%"+query.getDeptName()+"%"));
            }
            
            return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
        },sort);
        //是否要筛选还没有支部绑定的部门
        if (Objects.nonNull(query.getCanChoose()) && query.getCanChoose()) {
            depts = depts.stream().filter(d -> d.getBranchId() == null).collect(Collectors.toList());
        }
        return depts;
    }

    @Override
    public void saveDepartment(InspectionDepartmentDTO save) {
        InspectionDepartmentDO saveDO = new InspectionDepartmentDO();
        BeanUtils.copyProperties(save, saveDO);
        saveDO.setDeptType(Objects.isNull(save.getDeptType())? DepartmentTypeEnum.UN_EXECUTOR_DEPT.getValue():save.getDeptType());
        saveDO.setDateCreate(new Date());
        saveDO.setIsDel(0);
        saveDO.setParentId(Objects.isNull(save.getParentId()) ? -1 : save.getParentId());
        saveDO.setIsLeafNode(Objects.isNull(save.getIsLeafNode()) ? YesNoEnum.YES.getVal() : save.getIsLeafNode());
        inspectionDepartmentDao.save(saveDO);
    }

    @Override
    public void delDepartment(InspectionDepartmentDTO del) {
        AssertUtils.nonNull(del.getId(),"部门id不能为空");
        InspectionDepartmentDO deptParam = new InspectionDepartmentDO();
        deptParam.setId(del.getId());
        deptParam.setIsDel(0);
        Optional<InspectionDepartmentDO> deptOp = inspectionDepartmentDao.findOne(Example.of(deptParam));
        if(!deptOp.isPresent()){
            throw new BusinessBaseException("部门不存在");
        }
        InspectionDepartmentDO deptUpdate = deptOp.get();
        deptUpdate.setIsDel(1);
        inspectionDepartmentDao.saveAndFlush(deptUpdate);
    }

    @Override
    public InspectionDepartmentDO getDepartment(InspectionDepartmentQueryDTO query) {
        AssertUtils.nonNull(query.getId(), "部门id不能为空");
        InspectionDepartmentDO deptParam = new InspectionDepartmentDO();
        deptParam.setId(query.getId());
        deptParam.setIsDel(0);
        Optional<InspectionDepartmentDO> deptOp = inspectionDepartmentDao.findOne(Example.of(deptParam));
        if (!deptOp.isPresent()) {
            throw new BusinessBaseException("部门不存在");
        }
        return deptOp.get();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateDepartment(InspectionDepartmentDTO update) {
        AssertUtils.nonNull(update.getId(), "部门id不能为空");
        InspectionDepartmentDO deptParam = new InspectionDepartmentDO();
        deptParam.setId(update.getId());
        deptParam.setIsDel(0);
        Optional<InspectionDepartmentDO> deptOp = inspectionDepartmentDao.findOne(Example.of(deptParam));
        if (!deptOp.isPresent()) {
            throw new BusinessBaseException("部门不存在");
        }
        InspectionDepartmentDO deptUpdate = deptOp.get();
        deptUpdate.setDeptType(update.getDeptType());
        deptUpdate.setDeptDesc(update.getDeptDesc());
        deptUpdate.setDeptName(update.getDeptName());
        inspectionDepartmentDao.saveAndFlush(deptUpdate);
    }
}


